package com.campus.delivery.service;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.common.bean.common.PageUtil;
import com.campus.delivery.bean.earnings.EarningsQueryParam;
import com.campus.delivery.entity.DeliveryDailyEarnings;
import com.campus.delivery.mapper.DeliveryDailyEarningsMapper;
import com.campus.delivery.vo.earnings.EarningsRecordVo;
import com.campus.delivery.vo.earnings.EarningsStatisticsVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.Data;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 配送员每日收益汇总表 服务实现类
 * </p>
 *
 * @author ZhaoYuJie
 * @since 2025-06-13
 */
@Service
public class DeliveryDailyEarningsService extends ServiceImpl<DeliveryDailyEarningsMapper, DeliveryDailyEarnings> {

    /**
     * 获取配送员昨日收益
     */
    public BigDecimal getYesterdayEarnings(Long deliveryId) {
        LambdaQueryWrapper<DeliveryDailyEarnings> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeliveryDailyEarnings::getDeliveryId, deliveryId)
                   .eq(DeliveryDailyEarnings::getEarningDate, LocalDate.now().minusDays(1));
        
        DeliveryDailyEarnings yesterdayRecord = this.getOne(queryWrapper);
        return yesterdayRecord != null ? yesterdayRecord.getTotalEarnings() : BigDecimal.ZERO;
    }

    /**
     * 获取配送员累计收益
     */
    public BigDecimal getTotalEarnings(Long deliveryId) {
        LambdaQueryWrapper<DeliveryDailyEarnings> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeliveryDailyEarnings::getDeliveryId, deliveryId)
                   .select(DeliveryDailyEarnings::getTotalEarnings);
        
        List<DeliveryDailyEarnings> records = this.list(queryWrapper);
        return records.stream()
                .map(DeliveryDailyEarnings::getTotalEarnings)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    /**
     * 获取配送员收益统计
     */
    private EarningsStatistics getEarningsStatistics(Long deliveryId, LocalDate startDate, LocalDate endDate) {
        EarningsStatistics statistics = new EarningsStatistics();
        
        // 如果没有指定日期范围，默认查询最近30天
        if (startDate == null && endDate == null) {
            endDate = LocalDate.now();
            startDate = endDate.minusDays(29);
        }
        
        LambdaQueryWrapper<DeliveryDailyEarnings> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeliveryDailyEarnings::getDeliveryId, deliveryId);
        
        if (startDate != null) {
            queryWrapper.ge(DeliveryDailyEarnings::getEarningDate, startDate);
        }
        if (endDate != null) {
            queryWrapper.le(DeliveryDailyEarnings::getEarningDate, endDate);
        }
        
        List<DeliveryDailyEarnings> records = this.list(queryWrapper);
        
        // 计算统计数据
        BigDecimal totalEarnings = records.stream()
                .map(DeliveryDailyEarnings::getTotalEarnings)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        
        Integer totalOrders = records.stream()
                .mapToInt(DeliveryDailyEarnings::getTotalOrders)
                .sum();
        
        Integer workDays = records.size();
        
        // 设置统计数据
        statistics.setTotalEarnings(totalEarnings);
        statistics.setTotalOrders(totalOrders);
        statistics.setWorkDays(workDays);
        
        // 计算平均日收益
        BigDecimal avgDailyEarnings = workDays > 0 ? 
            totalEarnings.divide(new BigDecimal(workDays), 2, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO;
        statistics.setAvgDailyEarnings(avgDailyEarnings);
        
        statistics.setStartDate(startDate);
        statistics.setEndDate(endDate);
        
        return statistics;
    }

    /**
     * 获取配送员收益统计（返回VO对象）
     */
    public EarningsStatisticsVo getEarningsStatisticsVo(Long deliveryId) {
        EarningsStatisticsVo vo = new EarningsStatisticsVo();
        
        // 昨日收益
        vo.setYesterdayEarnings(getYesterdayEarnings(deliveryId));
        
        // 累计收益
        vo.setTotalEarnings(getTotalEarnings(deliveryId));
        
        // 本月收益
        LocalDate monthStart = LocalDate.now().withDayOfMonth(1);
        LocalDate monthEnd = LocalDate.now();
        EarningsStatistics monthStats = getEarningsStatistics(deliveryId, monthStart, monthEnd);
        vo.setMonthEarnings(monthStats.getTotalEarnings());
        
        // 总订单数
        LambdaQueryWrapper<DeliveryDailyEarnings> totalOrdersQuery = new LambdaQueryWrapper<>();
        totalOrdersQuery.eq(DeliveryDailyEarnings::getDeliveryId, deliveryId);
        List<DeliveryDailyEarnings> allRecords = this.list(totalOrdersQuery);
        Integer totalOrders = allRecords.stream()
                .mapToInt(DeliveryDailyEarnings::getTotalOrders)
                .sum();
        vo.setTotalOrders(totalOrders);
        
        return vo;
    }

    /**
     * 收益统计内部类
     */
    @Data
    private static class EarningsStatistics {
        private BigDecimal totalEarnings;
        private Integer totalOrders;
        private Integer workDays;
        private BigDecimal avgDailyEarnings;
        private LocalDate startDate;
        private LocalDate endDate;
    }

    /**
     * 获取配送员收益记录（分页）
     */
    public PageInfo<EarningsRecordVo> getEarningsRecords(EarningsQueryParam param) {
        LambdaQueryWrapper<DeliveryDailyEarnings> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeliveryDailyEarnings::getDeliveryId, param.getDeliveryId());
        
        if (param.getStartDate() != null) {
            queryWrapper.ge(DeliveryDailyEarnings::getEarningDate, param.getStartDate());
        }
        if (param.getEndDate() != null) {
            queryWrapper.le(DeliveryDailyEarnings::getEarningDate, param.getEndDate());
        }
        
        queryWrapper.orderByDesc(DeliveryDailyEarnings::getEarningDate);
        
        PageInfo<DeliveryDailyEarnings> pageInfo = PageHelper.startPage(param.getPageNo(), param.getPageSize())
                .doSelectPageInfo(() -> list(queryWrapper));
        
        List<EarningsRecordVo> voList = pageInfo.getList().stream()
                .map(this::convertToVo)
                .collect(Collectors.toList());
        
        return PageUtil.convertPageInfo(pageInfo, voList);
    }

    /**
     * 转换实体对象为VO对象
     */
    private EarningsRecordVo convertToVo(DeliveryDailyEarnings entity) {
        EarningsRecordVo vo = new EarningsRecordVo();
        BeanUtil.copyProperties(entity, vo);
        return vo;
    }
}
